package com.zhitxx.weight

import android.content.Context
import android.graphics.*
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.os.Parcelable
import android.util.AttributeSet
import android.util.TypedValue
import androidx.annotation.Nullable
import androidx.appcompat.widget.AppCompatImageView


/**
 * 自定义ImageView  有圆角、圆形、多边形
 */
class SelfImageView : AppCompatImageView {

    /**
     * 图片的类型，圆形or圆角or多边形
     */
    private var mContext: Context? = null

    /**
     * 传输类型
     */
    private var type = 0

    /**
     * 圆形
     */
    val TYPE_CIRCLE = 0

    /**
     * 圆角
     */
    val TYPE_ROUND = 1

    /**
     * 多边形
     */
    val TYPE_MULTI = 3

    /**
     * 默认多边形角的个数
     */
    val ANGLECOUNT = 5

    /**
     * 默认开始绘制的角度
     */
    val CURRENTANGLE = 180

    /**
     * 多边形的半径
     */
    private var startRadius = 0

    /**
     * 多边形角的个数
     */
    private var angleCount = 0

    private lateinit var angles: IntArray

    /**
     * 开始绘制的角度
     */
    private var currentAngle = 0

    /**
     * 存储角位置的集合
     */
    private val pointFList: MutableList<PointF> = ArrayList()

    /**
     * 圆角大小的默认值
     */
    private val BODER_RADIUS_DEFAULT = 10

    /**
     * 圆角的大小
     */
    private var mBorderRadius = 0

    /**
     * 绘图的Paint
     */
    private var mBitmapPaint: Paint? = null

    /**
     * 圆角的半径
     */
    private var mRadius = 0

    /**
     * 3x3 矩阵，主要用于缩小放大
     */
    private var mMatrix: Matrix? = null

    /**
     * 渲染图像，使用图像为绘制图形着色
     */
    private var mBitmapShader: BitmapShader? = null

    /**
     * view的宽度
     */
    private var mWidth = 0
    private var mRoundRect: RectF? = null


    constructor (context: Context?) : this(context, null)

    constructor(context: Context?, attrs: AttributeSet?) : this(context!!, attrs, 0)


    constructor(context: Context, @Nullable attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
        mContext = context
        init(context, attrs)
    }

    fun init(context: Context, attrs: AttributeSet?) {
        mMatrix = Matrix()
        mBitmapPaint = Paint()
        mBitmapPaint!!.setAntiAlias(true)
        val typedArray = context.obtainStyledAttributes(attrs,
                R.styleable.RoundImageView)
        mBorderRadius = typedArray.getDimensionPixelSize(
                R.styleable.RoundImageView_borderRadius, TypedValue
                .applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                        BODER_RADIUS_DEFAULT.toFloat(), resources
                        .displayMetrics).toInt()) // 默认为10dp
        type = typedArray.getInt(R.styleable.RoundImageView_type, TYPE_CIRCLE) // 默认为Circle
        angleCount = typedArray.getInt(R.styleable.RoundImageView_angleCount, ANGLECOUNT)
        currentAngle = typedArray.getInt(R.styleable.RoundImageView_currentAngle, currentAngle)
        typedArray.recycle() //回收之后对象可以重用
    }


    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        /**
         * 如果类型是圆形或多边形，则强制改变view的宽高一致，以小值为准
         */
        if (type == TYPE_CIRCLE) {
            mWidth = Math.min(measuredWidth, measuredHeight)
            mRadius = mWidth / 2
            setMeasuredDimension(mWidth, mWidth)
        }
        if (type == TYPE_MULTI) {
            mWidth = Math.min(measuredWidth, measuredHeight)
            setMeasuredDimension(mWidth, mWidth)
            angles = IntArray(angleCount)
            for (i in 0 until angleCount) {
                val partOfAngle = 360 / angleCount //每个顶点的角度
                angles[i] = currentAngle + partOfAngle * i
                startRadius = mWidth / 2
                val x = (Math.sin(Math.toRadians(angles[i].toDouble())) * startRadius).toFloat()
                val y = (Math.cos(Math.toRadians(angles[i].toDouble())) * startRadius).toFloat()
                pointFList.add(PointF(x, y))
            }
        }
    }

    /**
     * 初始化BitmapShader
     */
    private fun setUpShader() {
        val drawable = drawable ?: return
        val bmp = drawableToBitamp(drawable)
        // 将bmp作为着色器，就是在指定区域内绘制bmp
        mBitmapShader = BitmapShader(bmp, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT)
        var scale = 1.0f
        if (type == TYPE_CIRCLE) {
            // 拿到bitmap宽或高的小值
            val bSize = Math.min(bmp.width, bmp.height)
            scale = mWidth * 1.0f / bSize
        } else if (type == TYPE_ROUND) {
            if (!(bmp.width == width && bmp.height == height)) {
                // 如果图片的宽或者高与view的宽高不匹配，计算出需要缩放的比例；缩放后的图片的宽高，一定要大于我们view的宽高；所以我们这里取大值；
                scale = Math.max(width * 1.0f / bmp.width, height * 1.0f / bmp.height)
            }
        } else if (type == TYPE_MULTI) {
            // 拿到bitmap宽或高的小值
            val bSize = Math.min(bmp.width, bmp.height)
            scale = mWidth * 1.0f / bSize
        }
        // shader的变换矩阵，我们这里主要用于放大或者缩小
        mMatrix!!.setScale(scale, scale)

        // 设置变换矩阵
        mBitmapShader!!.setLocalMatrix(mMatrix)
        // 设置shader
        mBitmapPaint!!.setShader(mBitmapShader)
    }

    override fun onDraw(canvas: Canvas) {
        if (drawable == null) {
            return
        }
        setUpShader()
        if (type == TYPE_ROUND) {
            canvas.drawRoundRect(mRoundRect!!, mBorderRadius.toFloat(), mBorderRadius.toFloat(),
                    mBitmapPaint!!)
        } else if (type == TYPE_MULTI) {
            //canvas.translate(startRadius,startRadius);
            val mPath: Path = drawPath()
            canvas.drawPath(mPath, mBitmapPaint!!)
        } else {
            canvas.drawCircle(mRadius.toFloat(), mRadius.toFloat(), mRadius.toFloat(), mBitmapPaint!!)
        }
    }

    /**
     * @return 多边形路径
     */
    private fun drawPath(): Path {
        val mPath = Path()
        mPath.moveTo(pointFList[0].x, pointFList[0].y)
        for (i in 2 until angleCount) {
            if (i % 2 == 0) { // 除以二取余数，余数为0则为偶数,否则奇数
                mPath.lineTo(pointFList[i].x, pointFList[i].y)
            }
        }
        if (angleCount % 2 == 0) {  //偶数，moveTo
            mPath.moveTo(pointFList[1].x, pointFList[1].y)
        } else {                    //奇数，lineTo
            mPath.lineTo(pointFList[1].x, pointFList[1].y)
        }
        for (i in 3 until angleCount) {
            if (i % 2 != 0) {
                mPath.lineTo(pointFList[i].x, pointFList[i].y)
            }
        }
        mPath.offset(startRadius.toFloat(), startRadius.toFloat())
        return mPath
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)

        // 圆角图片的范围
        if (type == TYPE_ROUND) mRoundRect = RectF(0f, 0f, w.toFloat(), h.toFloat())
    }

    /**
     * drawable转bitmap
     *
     * @param drawable
     * @return
     */
    private fun drawableToBitamp(drawable: Drawable): Bitmap {
        if (drawable is BitmapDrawable) {
            return drawable.bitmap
        }
        val w = drawable.intrinsicWidth
        val h = drawable.intrinsicHeight
        val bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        drawable.setBounds(0, 0, w, h)
        drawable.draw(canvas)
        return bitmap
    }

    private val STATE_INSTANCE = "state_instance"
    private val STATE_TYPE = "state_type"
    private val STATE_BORDER_RADIUS = "state_border_radius"

    override fun onSaveInstanceState(): Parcelable? {
        val bundle = Bundle()
        bundle.putParcelable(STATE_INSTANCE, super.onSaveInstanceState())
        bundle.putInt(STATE_TYPE, type)
        bundle.putInt(STATE_BORDER_RADIUS, mBorderRadius)
        return bundle
    }

    override fun onRestoreInstanceState(state: Parcelable?) {
        if (state is Bundle) {
            val bundle = state
            super.onRestoreInstanceState(state
                    .getParcelable(STATE_INSTANCE))
            type = bundle.getInt(STATE_TYPE)
            mBorderRadius = bundle.getInt(STATE_BORDER_RADIUS)
        } else {
            super.onRestoreInstanceState(state)
        }
    }

    fun setType(type: Int) {
        if (this.type != type) {
            this.type = type
            if (this.type != TYPE_ROUND && this.type != TYPE_CIRCLE && this.type != TYPE_MULTI) {
                this.type = TYPE_CIRCLE
            }
            requestLayout()
        }
    }


}